package net.guerlab.smart.platform.user.api.autoconfig;

import lombok.AllArgsConstructor;
import net.guerlab.smart.platform.commons.util.BeanConvertUtils;
import net.guerlab.smart.platform.user.api.UserOauthApi;
import net.guerlab.smart.platform.user.core.entity.UserOauthDTO;
import net.guerlab.smart.platform.user.core.exception.UserHasNotBoundException;
import net.guerlab.smart.platform.user.core.searchparams.UserOauthSearchParams;
import net.guerlab.smart.platform.user.service.service.UserOauthService;
import net.guerlab.web.result.ListObject;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.*;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.lang.NonNull;

import java.util.List;

/**
 * @author guer
 */
@Configuration
@Conditional(UserOauthApiLocalServiceAutoConfigure.WrapperCondition.class)
public class UserOauthApiLocalServiceAutoConfigure {

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Bean
    @ConditionalOnBean(UserOauthService.class)
    public UserOauthApi userOauthApiLocalServiceWrapper(UserOauthService service) {
        return new UserOauthApiLocalServiceWrapper(service);
    }

    @SuppressWarnings("WeakerAccess")
    static class WrapperCondition implements Condition {

        @Override
        public boolean matches(@NonNull ConditionContext context, @NonNull AnnotatedTypeMetadata metadata) {
            try {
                ClassLoader classLoader = WrapperCondition.class.getClassLoader();
                return classLoader.loadClass("net.guerlab.smart.platform.user.service.service.UserOauthService")
                        != null;
            } catch (Exception e) {
                return false;
            }
        }
    }

    @AllArgsConstructor
    private static class UserOauthApiLocalServiceWrapper implements UserOauthApi {

        private final UserOauthService service;

        @Override
        public UserOauthDTO findOne(String type, Long userId) {
            return service.getOneOptional(type, userId).orElseThrow(UserHasNotBoundException::new).toDTO();
        }

        @Override
        public ListObject<UserOauthDTO> findList(UserOauthSearchParams searchParams) {
            return BeanConvertUtils.toListObject(service.selectPage(searchParams));
        }

        @Override
        public List<UserOauthDTO> findAll(UserOauthSearchParams searchParams) {
            return BeanConvertUtils.toList(service.selectAll(searchParams));
        }
    }
}
